package com.lty.protocol.tcp.handler;

import com.lty.protocol.tcp.dto.RemoteClient;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.net.InetSocketAddress;
import java.sql.Connection;
import java.sql.ResultSet;
import java.text.MessageFormat;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName ServerHandler
 * @Description 服务处理器
 */
@Slf4j
public class ServerHandler extends ChannelInboundHandlerAdapter {

    // 存储远程客户端信息(key: channelId, value: RemoteClient)
    private Map<String, RemoteClient> remoteClients = new HashMap<>();

    // 默认客户回码
    private static String commonCode = "client";

    private Connection connection = null;
    private ResultSet resultSet = null;

    // private static TcpMessageService tcpMessageService;
    // private static TcpClientService tcpClientService;
    //
    // static {
    //     tcpMessageService = SpringUtil.getBean(TcpMessageService.class);
    //     tcpClientService = SpringUtil.getBean(TcpClientService.class);
    // }

    /**
     * 客户端连接处理
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        String remoteAddress = ctx.channel().remoteAddress().toString().replace("/", "").split(":")[0];
        String channelId = ctx.channel().id().toString();
        RemoteClient remoteClient = new RemoteClient();
        remoteClient.setAddr(remoteAddress);
        remoteClient.setLastRecordTime(LocalDateTime.now().toString());
        remoteClient.setLastData("0");
        remoteClients.put(channelId, remoteClient);
        // 客户端连接时触发，可以记录连接信息
        InetSocketAddress socketAddress = (InetSocketAddress) ctx.channel().remoteAddress();
        String clientAdd = socketAddress.getAddress().getHostAddress();
        Integer port = socketAddress.getPort();
        // 初始化客户端
        initByte(ctx.channel());
        // 发送回码给客户端
        // sendResponseByte(ctx.channel());
        try {
            // TODO 数据库中记录或更新客户端状态
        } catch (Exception e) {
            log.error("初始化客户端信息失败: {}", e.getMessage());
        }
        super.channelActive(ctx);
    }

    /**
     * 处理接收到的消息
     *
     * @param ctx 上下文
     * @param msg 接收到的消息
     * @throws Exception 异常
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Channel channel = ctx.channel();
        String channelId = channel.id().toString();
        String remoteAddress = channel.remoteAddress().toString().replace("/", "").split(":")[0];
        String logOut = MessageFormat.format("channelId:{0}>>>>>>>>ip:{1}>>>>>>>>>msg:{2}", channelId, remoteAddress, msg);
        log.info(logOut);

        handleReadData(ctx, msg);    // 处理解析数据
        sendResponseByte(ctx.channel());  // 发送回码给客户端

        // 如果tcpServer后续还有待处理的Handler则需要传递消息
        // super.channelRead(ctx, msg);
    }

    /**
     * 处理解析数据
     *
     * @param ctx 上下文
     * @param msg 消息
     * @throws ParseException 解析异常
     */
    private void handleReadData(ChannelHandlerContext ctx, Object msg) throws ParseException {
        Channel channel = ctx.channel();
        String channelId = channel.id().toString();
        String remoteAddress = channel.remoteAddress().toString().replace("/", "").split(":")[0];
        String payload = "";
        if (msg instanceof String) {
            payload = (String) msg;
        }
        // 解析数据
        if (StringUtils.isNotBlank(payload)) {
            // TODO 解析数据方法
            // System.out.println("解析数据: " + payload);
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        String channelId = channel.id().toString();
        remoteClients.remove(channelId);
        // TODO 更新客户端状态为不活跃
        try {
        } catch (Exception e) {
            log.error("更新客户端状态失败: {}", e.getMessage());
        }
        super.channelInactive(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 记录异常日志
        log.error("发生异常: {}", cause.getMessage(), cause);
        // 关闭连接
        ctx.close();
    }

    /**
     * 发送响应回码给客户端
     */
    private void sendResponseByte(Channel ctx) {
        byte[] responseBytes = commonCode.getBytes();
        ByteBuf response = Unpooled.wrappedBuffer(responseBytes);
        // 发送回码给客户端
        ctx.writeAndFlush(response);
    }

    /**
     * 初始化客户端信息
     */
    private void initByte(Channel ctx) {
        byte[] initByte = commonCode.getBytes();
        log.info("初始化客户端信息:" + commonCode);
        ByteBuf responseInit = Unpooled.wrappedBuffer(initByte);
        // 发送回码给客户端
        ctx.writeAndFlush(responseInit);
    }
}
